package com.ely.coupon.distribute.service.impl;


import cn.hutool.core.date.DateUtil;
import com.ely.coupon.activity.dto.CouponActivityInfo;
import com.ely.coupon.common.core.ex.ServiceException;
import com.ely.coupon.common.core.result.ResponseCode;
import com.ely.coupon.common.core.result.ResponseResult;
import com.ely.coupon.distribute.entity.Coupon;
import com.ely.coupon.distribute.feign.CouponActivityFeignClient;
import com.ely.coupon.distribute.mapper.CouponMapper;
import com.ely.coupon.distribute.service.CouponDistributeService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Optional;

/**
 * 消息系统
 * <p>
 * 站内信   短信  腾讯  阿里云 华为   邮件   163   qq  阿里云   微信通知
 */
@Service
public class CouponDistributeServiceImpl implements CouponDistributeService {
    @Autowired
    private CouponActivityFeignClient activityFeignClient;
    @Resource
    private CouponMapper couponMapper;

    /**
     * 存在的问题
     * 分布式事务  操作不通的数据库  seata
     * 数据库安全  分布式锁 因为分发系统是集群,所有需要使用分布式   redisson  分布式锁
     * 业务在哪里判断
     * 后台 分页查询优惠券信息 ---> 前端 用户查看优惠券信息 --->   用户点击领取按钮 ----> 后台领取优惠券接口----->
     *
     * @param memberId
     * @param couponActivityId
     * @return
     */
    @GlobalTransactional
    @Override
    public int receive(Long memberId, Long couponActivityId) {
        // 优惠券活动系统获取 优惠券活动信息
        ResponseResult<CouponActivityInfo> result = activityFeignClient.getCouponActivityInfo(couponActivityId);
        if (result.getCode() != 200 || ObjectUtils.isEmpty(result.getData())) {
            throw new ServiceException(ResponseCode.COUPON_NO_EXIST_ERROR);
        }
        //  判断库存是否足够
        CouponActivityInfo couponActivityInfo = result.getData();
        // 获取优惠卷的库存数
        Integer couponQuantity = couponActivityInfo.getCouponQuantity();
        if (couponQuantity < 1) {
            throw new ServiceException(ResponseCode.COUPON_NO_STORE_ERROR);
        }
        //  判断领取的最大数量
        Long count = couponMapper.selectCouponCount(memberId, couponActivityId);
        if (!ObjectUtils.isEmpty(count) && count >= couponActivityInfo.getMaxReceiveCount()) {
            throw new ServiceException(ResponseCode.COUPON_MAX_ERROR);
        }
        //从redis 获取优惠卷码   活动结束时间
        Date expireDate = couponActivityInfo.getExpiryDateType() == 1 ? DateUtil.offsetDay(new Date(), couponActivityInfo.getExpiryDay()) : couponActivityInfo.getExpiryEndDate();
        Coupon coupon = new Coupon();
        coupon.setCouponActivityId(couponActivityId);
        coupon.setMemberId(memberId);
        coupon.setExpireDate(expireDate);
        int rowNum = couponMapper.insert(coupon);
        if (rowNum <= 0) {
            throw new ServiceException(ResponseCode.SYS_ERROR);
        }
        // 更新优惠卷库存
        activityFeignClient.decrease(couponActivityId, couponQuantity - 1);
        return rowNum;
    }


    /**
     * 保存会员优惠券信息
     *
     * @param memberId 会员ID
     * @return 返回插入的行数
     * @throws ServiceException 如果获取优惠券活动信息失败或处理过程中遇到系统错误
     */
    @Override
    public int save(Long memberId) {
        // 调用Feign客户端获取新的优惠券活动信息
        ResponseResult<CouponActivityInfo> result = activityFeignClient.getNewCouponInfo(3);

        // 检查结果状态，如果不成功，则抛出系统异常
        if (result.getCode() != 200) {
            throw new ServiceException(ResponseCode.SYS_ERROR);
        }

        // 获取优惠券活动信息，如果为空，则抛出系统异常
        CouponActivityInfo couponActivityInfo = Optional.ofNullable(result.getData())
                .orElseThrow(() -> new ServiceException(ResponseCode.SYS_ERROR));

        // 创建优惠券实体并设置属性
        Coupon coupon = new Coupon();
        coupon.setMemberId(memberId);
        coupon.setCouponActivityId(couponActivityInfo.getCouponActivityId());
        coupon.setExpireDate(couponActivityInfo.getExpiryEndDate());

        // 插入优惠券信息到数据库并返回影响的行数
        return couponMapper.insert(coupon);
    }
}
